#include <STC89C5xRC.H>

sbit DS1302_SCLK=P3^6;
sbit DS1302_IO=P3^4;
sbit DS1302_CE=P3^5;


#define DS1302_SECOND 	0x80
#define DS1302_MINUTE 	0x82
#define DS1302_HOUR 		0x84
#define DS1302_DATE 		0x86
#define DS1302_MONTH 		0x88
#define DS1302_DAY 			0x8a
#define DS1302_YEAR 		0x8c
#define DS1302_WP 			0x8e//注意：这条语句后面不能加分号！！！！！！！

char DS1302_Time[]={24,7,31,10,20,31,3};

/**
 * @brief 初始化DS1302时钟芯片
 * @param 无
 * @retval 无
 **/
void DS1302_Init()
{	
	DS1302_IO=0;//不加这一行会显示255
	DS1302_CE=0;
	DS1302_SCLK=0;
}

/**
 * @brief 写入数据
 * @param Command，告诉DS1302芯片写入的地址
 * @param Data，要写入的数据
 * @retval 无
 **/
unsigned char i;//全局变量定义好后默认是0

void DS1302_WriteByte(unsigned char Command,Data)
{	
	DS1302_CE=1;
	for(i=0;i<8;i++)
	{
		DS1302_IO=Command&(0x01<<i);//先读最低位
		DS1302_SCLK=1;//注意：置1后马上置0需要考虑芯片能接受的最大速率，查芯片手册
		DS1302_SCLK=0;//单片机速率不高，不用加延时可马上在置1后置0
	}
		for(i=0;i<8;i++)
	{
		DS1302_IO=Data&(0x01<<i);
		DS1302_SCLK=1;
		DS1302_SCLK=0;
	}
	DS1302_CE=0;
}

/**
 * @brief 读取所需地址的数据
 * @param Command，告诉DS1302需要读取的地址
 * @retval 返回读出的数据
 **/
unsigned char DS1302_ReadByte(unsigned char Command)
{	
	unsigned char Data=0x00;//局部变量定义好不一定是0
	Command |= 0x01;//简化操作
	DS1302_CE = 1;
	for(i=0;i<8;i++)
	{
		DS1302_IO=Command&(0x01<<i);
		DS1302_SCLK=0;
		DS1302_SCLK=1;
	}
	for(i=0;i<8;i++)
	{
		DS1302_SCLK=1;
		DS1302_SCLK=0;//先读取DS1302_IO的最低位，若为1，则是读模式
		if(DS1302_IO){Data|=(0x01<<i);}
	}
	DS1302_CE=0;
	DS1302_IO=0;
	return Data;	
}

/**
 * @brief 将存放在数组的各时间信息写入DS1302的对应位置，并转换为BCD码写入
 * @param 无
 * @retval 无
 **/
void DS1302_SetTime()
{
	DS1302_WriteByte(DS1302_WP,0x00);//关闭写保护
	DS1302_WriteByte(DS1302_YEAR,DS1302_Time[0]/10*16+DS1302_Time[0]%10);
	DS1302_WriteByte(DS1302_MONTH,DS1302_Time[1]/10*16+DS1302_Time[1]%10);
	DS1302_WriteByte(DS1302_DATE,DS1302_Time[2]/10*16+DS1302_Time[2]%10);
	DS1302_WriteByte(DS1302_HOUR,DS1302_Time[3]/10*16+DS1302_Time[3]%10);
	DS1302_WriteByte(DS1302_MINUTE,DS1302_Time[4]/10*16+DS1302_Time[4]%10);
	DS1302_WriteByte(DS1302_SECOND,DS1302_Time[5]/10*16+DS1302_Time[5]%10);
	DS1302_WriteByte(DS1302_DAY,DS1302_Time[6]/10*16+DS1302_Time[6]%10);
	DS1302_WriteByte(DS1302_WP,0x80);//打开写保护
}

/**
 * @brief 将写入的时间信息读出并将BCD码形式转换为十进制放回数组的对应位置中
 * @param 无
 * @retval 无
 **/
void DS1302_ReadTime()
{	
	unsigned char Temp;
	Temp=DS1302_ReadByte(DS1302_YEAR);
	DS1302_Time[0]=Temp/16*10+Temp%16;
	
	Temp=DS1302_ReadByte(DS1302_MONTH);
	DS1302_Time[1]=Temp/16*10+Temp%16;
	
	Temp=DS1302_ReadByte(DS1302_DATE);
	DS1302_Time[2]=Temp/16*10+Temp%16;
	
	Temp=DS1302_ReadByte(DS1302_HOUR);
	DS1302_Time[3]=Temp/16*10+Temp%16;
	
	Temp=DS1302_ReadByte(DS1302_MINUTE);
	DS1302_Time[4]=Temp/16*10+Temp%16;
	
	Temp=DS1302_ReadByte(DS1302_SECOND);
	DS1302_Time[5]=Temp/16*10+Temp%16;
	
	Temp=DS1302_ReadByte(DS1302_DAY);
	DS1302_Time[6]=Temp/16*10+Temp%16;

}